package jm.demo.jaxb.permission;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.SchemaOutputResolver;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.AnnotationIntrospector;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.xc.JaxbAnnotationIntrospector;

import com.sun.jersey.api.json.JSONJAXBContext;
import com.sun.jersey.api.json.JSONMarshaller;
import com.sun.jersey.api.json.JSONUnmarshaller;

public class Main {
    

    
    public static void testJson(SecurityContextType sc) {
        try {
            
        	
            
            JAXBContext jaxb = JSONJAXBContext.newInstance(
                    Role.class
                    , SecurityContextType.class
                    , SecurityObject.class
            );
            JSONMarshaller marshaller = JSONJAXBContext.getJSONMarshaller(jaxb.createMarshaller());
            StringWriter sw = new StringWriter();
            marshaller.marshallToJSON(sc, sw);
            String json_value = sw.toString();
            System.out.println(json_value);
            
            JSONUnmarshaller unmarshaller = JSONJAXBContext.getJSONUnmarshaller(jaxb.createUnmarshaller());
            SecurityContextType sc_clone = unmarshaller.unmarshalFromJSON(new StringReader(json_value), SecurityContextType.class);
            
            System.out.println("Reading object is equals to the original one: " + sc_clone.equals(sc));
            sc_clone.getRoles().get(0).getSecurityObjects().get(0).setName("who konws");
            System.out.println("Reading object is equals to the original one: " + sc_clone.equals(sc));
            
            
        	final Writer writer = new StringWriter();
        	
        	class MySchemaOutputResolver extends SchemaOutputResolver {
        	    public Result createOutput( String namespaceUri, String suggestedFileName ) throws IOException {
        	    	StreamResult result = new StreamResult(writer);
        	    	result.setSystemId("aaaa");
        	    	return result;
        	    }
        	}

            
            SchemaOutputResolver outputResolver = new MySchemaOutputResolver();
			jaxb.generateSchema(outputResolver );
			System.out.println("--- Generate schema ---");
			System.out.println(writer.toString());
        } catch (JAXBException e) {
            e.printStackTrace();
        } catch (IOException e) {
			e.printStackTrace();
		}
    }
    
    public static void testJsonByJackson(SecurityContextType sc) {
        ObjectMapper mapper = new ObjectMapper();
        AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();

        /*
         *         
        AnnotationIntrospector primary = new JacksonAnnotationIntrospector();
        AnnotationIntrospector secondary = new JaxbAnnotationIntrospector();
        AnnotationIntrospector pair = new AnnotationIntrospector.Pair(primaryIntrospector, secondaryIntropsector);
        
         */
        
        
        // make deserializer use JAXB annotations (only)
        mapper.getDeserializationConfig().setAnnotationIntrospector(introspector);
        // make serializer use JAXB annotations (only)
        mapper.getSerializationConfig().setAnnotationIntrospector(introspector);
        
        String json_value = "";
        try {
            json_value = mapper.writeValueAsString(sc);
            System.out.println(json_value);
        } catch (JsonGenerationException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        try {
            // SecurityContext sc_clone = (SecurityContext)mapper.reader(SecurityContext.class).readValue(json_value);
        	SecurityContextType sc_clone = mapper.readValue(json_value, SecurityContextType.class);
            
            System.out.println("Reading object is equals to the original one: " + sc_clone.equals(sc));
            sc_clone.getRoles().get(0).getSecurityObjects().get(0).setName("who konws");
            System.out.println("Reading object is equals to the original one: " + sc_clone.equals(sc));
            System.out.println("----------");
            System.out.println(mapper.generateJsonSchema(SecurityContextType.class));
            
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        SecurityContextType sc = SecurityContextType.randomOne();
        // testJson(sc);
        System.out.println("------------");
        // testJsonByJackson(sc);
        testJson(sc);

    }

}
